import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Point;
import java.util.ArrayList;
import java.util.LinkedList;

import org.rsbot.script.Script;
import org.rsbot.script.ScriptManifest;
import org.rsbot.event.events.MessageEvent;
import org.rsbot.event.events.ServerMessageEvent;
import org.rsbot.event.listeners.MessageListener;
import org.rsbot.event.listeners.PaintListener;
import org.rsbot.event.listeners.ServerMessageListener;
import org.rsbot.script.wrappers.*;

import java.awt.event.KeyEvent; //Antiban
import java.awt.event.KeyListener;
import org.rsbot.script.methods.*;

import java.awt.*;
import javax.imageio.ImageIO;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.awt.event.*;
import java.awt.geom.GeneralPath;
import java.awt.image.BufferedImage;

import javax.swing.*;
import javax.swing.UIManager.LookAndFeelInfo;

/*
 * Credits - 
 * 
 * Thanks to Ramus for his awesome Line Mesh walking
 * Thanks to Ubuntu4life for snippets of his crafting scripts
 * 
 * 
 * 
 * 
 * 
 */


@ScriptManifest(authors = "Trolololoish, Delano_D, Doout, ", name = "<html><body bgcolor=blue><center><font color=ffffff>Falador Summoner", version = 0.97, description = "<html><body bgcolor=blue><font color=ffffff>Start in falador's west bank with bank closed, look at thread for more information!")
// Updated by Trolololoish

public class Falasum extends Script implements PaintListener, MessageListener {

	ArrayList<Pouch> pouch = new ArrayList<Pouch>();
	public boolean showPaint = false;
	public long runTime = 0, seconds = 0, minutes = 0, hours = 0;
	public int gainedExp = 0;
	public int expToLevel = 0;
	public long secToLevel = 0;
	public long minutesToLevel = 0;
	public long hoursToLevel = 0;
	private long startTime;
	private int startExp;
	private int startLevel;
	public float secExp = 0;
	public float minuteExp = 0;
	public float hourExp = 0;
	public String status;
	int doorClosed = 28690;
	int hatch = 4039;
	RSTile BankTile = new RSTile(2946, 3368);
	BufferedImage normal = null;
	BufferedImage clicked = null;

	public static final int[] BANK_BOOTHS = { 2213, 4483, 6084, 11402, 11758,
			12759, 14367, 19230, 24914, 25808, 26972, 27663, 29085, 34752,
			35647, 36786 };

	RSArea AREA_BANK = new RSArea(new RSTile(2943, 3368),
			new RSTile(2947, 3373));
	RSArea AREA_DOOR = new RSArea(new RSTile(2932, 3447),
			new RSTile(2941, 3453));
	RSArea AREA_TAV = new RSArea(new RSTile(2920, 3439), new RSTile(2927, 3448));
	RSArea AREA_SUMMONING = new RSArea(new RSTile(2204, 5341), new RSTile(2212,
			5350));

	private boolean inBankArea() {
		return AREA_BANK.contains(getMyPlayer().getLocation());
	}

	private boolean inDoorArea() {
		return AREA_DOOR.contains(getMyPlayer().getLocation());
	}

	private boolean inTavArea() {
		return AREA_TAV.contains(getMyPlayer().getLocation());
	}

	private boolean inSumArea() {
		return AREA_SUMMONING.contains(getMyPlayer().getLocation());
	}

	private static int PLACE;
	private static int CHARM;
	private static int ITEM_ID;
	public boolean isUp = true;

	// Summoning
	int SMstartLevel;
	int SMstartExp;
	int SMexpGained;
	int SMexpHour;
	int SMexpTillLevel;
	int SMtimeTillLevel;
	int SMcurrentLevel;
	int SMlevelsGained;
	int SMexpPercent;

	// 5-11-11

	private int nextStep = random(14, 20);

	ArrayList<RSTile> pathList;
	private Line[] LinetoTav = { new Line(2949, 3379, 2953, 3379),
			new Line(2962, 3385, 2966, 3385), new Line(2962, 3401, 2966, 3401),
			new Line(2959, 3412, 2960, 3417), new Line(2951, 3421, 2950, 3425),
			new Line(2948, 3437, 2947, 3442), new Line(2937, 3451, 2933, 3451),
			new Line(2926, 3441, 2924, 3444) };

	private Line[] LinetoBank = { new Line(2933, 3448, 2937, 3451),
			new Line(2948, 3439, 2948, 3446), new Line(2948, 3437, 2947, 3442),
			new Line(2951, 3421, 2950, 3425), new Line(2959, 3412, 2960, 3417),
			new Line(2962, 3401, 2966, 3401), new Line(2962, 3385, 2966, 3385),
			new Line(2949, 3379, 2953, 3379), new Line(2946, 3372, 2947, 3368), };

	// 5-11-11 End

	@Override
	public boolean onStart() {
		try {
			JFrame.setDefaultLookAndFeelDecorated(true);
			for (LookAndFeelInfo info : UIManager.getInstalledLookAndFeels()) {
				if ("Nimbus".equals(info.getName())) {
					UIManager.setLookAndFeel(info.getClassName());
					break;
				}
			}
		} catch (Exception e) {
			log.severe("Fail to setLookAndFeel");
		}
		AddPouch();
		new GUISum().setVisible(true);
		while (isUp == true) {
			sleep(650);
		}

		SMstartLevel = skills.getCurrentLevel(skills.SUMMONING);
		SMstartExp = skills.getCurrentExp(skills.SUMMONING);

		return true;
	}

	// START: Code generated using Enfilade's Easel
	private final RenderingHints antialiasing = new RenderingHints(
			RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);

	private Image getImage(String url) {
		try {
			return ImageIO.read(new URL(url));
		} catch (IOException e) {
			return null;
		}
	}

	private final Color color1 = new Color(51, 102, 255, 185);
	private final Color color2 = new Color(51, 102, 255, 207);
	private final Color color3 = new Color(255, 255, 255);
	private final Color percentbarBG = new Color(61, 61, 61);
	private final Color percentbarXPColor = new Color(170, 0, 0);
	private final BasicStroke stroke1 = new BasicStroke(1);
	private final Color WHITE = new Color(255, 255, 255);
	private final Color BLACK = new Color(0, 0, 0);
	private final Color MOUSE = new Color(20, 26, 167, 85);
	private final Font font1 = new Font("Castellar", 1, 18);
	private final Font font2 = new Font("Castellar", 1, 17);
	private final Font font3 = new Font("Copperplate Gothic Light", 0, 12);

	private final Image img1 = getImage("http://images3.wikia.nocookie.net/__cb20110305042731/runescape/images/e/e3/Summoning-icon.png");

	public void onRepaint(Graphics g1) {
		Graphics2D g = (Graphics2D) g1;
		g.setRenderingHints(antialiasing);
		if (startTime == 0) {
			startTime = System.currentTimeMillis();
		}

		if (startExp == 0) {
			startExp = skills.getCurrentExp(23);
		}

		if (startLevel == 0) {
			startLevel = skills.getRealLevel(23);
		}

		runTime = System.currentTimeMillis() - startTime;
		seconds = runTime / 1000;
		if (seconds >= 60) {
			minutes = seconds / 60;
			seconds -= minutes * 60;
		}
		if (minutes >= 60) {
			hours = minutes / 60;
			minutes -= hours * 60;
		}

		gainedExp = skills.getCurrentExp(23) - startExp;
		expToLevel = skills.getExpToNextLevel(23);

		if ((minutes > 0 || hours > 0 || seconds > 0) && gainedExp > 0) {
			secExp = (float) gainedExp
					/ (float) (seconds + minutes * 60 + hours * 60 * 60);
		}
		minuteExp = secExp * 60;
		hourExp = minuteExp * 60;

		if (secExp > 0) {
			secToLevel = (int) (expToLevel / secExp);
		}
		if (secToLevel >= 60) {
			minutesToLevel = secToLevel / 60;
			secToLevel -= minutesToLevel * 60;
		} else {
			minutesToLevel = 0;
		}
		if (minutesToLevel >= 60) {
			hoursToLevel = minutesToLevel / 60;
			minutesToLevel -= hoursToLevel * 60;
		} else {
			hoursToLevel = 0;
		}

		// Summoning
		SMcurrentLevel = skills.getCurrentLevel(Skills.SUMMONING);
		SMlevelsGained = SMcurrentLevel - SMstartLevel;
		SMexpGained = skills.getCurrentExp(Skills.SUMMONING) - SMstartExp;
		SMexpHour = (int) ((SMexpGained * 3600000.0) / (int) hourExp);
		SMexpTillLevel = skills.getExpToNextLevel(Skills.SUMMONING);
		SMtimeTillLevel = (int) (((double) SMexpTillLevel / (double) SMexpHour) * 3600000);
		SMexpPercent = skills.getPercentToNextLevel(Skills.SUMMONING);

		g.setColor(color1);
		g.fillRoundRect(307, 12, 208, 203, 16, 16);
		g.setColor(color2);
		g.setStroke(stroke1);
		g.drawRoundRect(307, 12, 208, 203, 16, 16);
		g.setFont(font1);
		g.setColor(color3);
		g.drawString("Fally Summoner", 311, 35);
		g.setFont(font2);
		g.setFont(font3);
		g.drawString("Time Running:" + hours + ":" + minutes + ":" + seconds,
				321, 64);
		g.drawString(
				"Exp Gained:" + gainedExp + " (Levels:"
						+ (skills.getRealLevel(23) - startLevel) + ")", 332, 81);
		g.drawString("Exp per hour:" + (int) hourExp, 317, 98);
		g.drawString("Exp TNL:" + expToLevel, 348, 116);
		g.drawString("Time to Level:" + hoursToLevel + ":" + minutesToLevel
				+ ":" + secToLevel, 314, 134);
		g.drawImage(img1, 318, 159, null);
		g.setColor(BLACK);
		g.drawRoundRect(355, 163, 131, 18, 16, 16);
		g.fillRoundRect(355, 163, 131, 18, 16, 16);
		g.setColor(percentbarXPColor);
		g.fillRoundRect(355, 163, (int) (SMexpPercent * 131 / 100.0), 18, 16,
				16);
		g.setColor(percentbarBG);
		g.setFont(font3);
		g.setColor(WHITE);
		g.drawString("" + SMcurrentLevel, 365, 177);
		g.drawString("" + (SMcurrentLevel + 1), 457, 177);
		g.drawString("" + SMexpPercent + "%", 407, 177);
		g.setColor(Color.black);
		g.drawRoundRect(355, 163, 131, 18, 16, 16);

		g.setColor(MOUSE);
		g.drawImage(normal, ((int) (mouse.getLocation().getX()) - 31),
				((int) (mouse.getLocation().getY()) - 31), null);
		final Point c = mouse.getPressLocation();

	}

	// 5-11-11
	private boolean firstRun = true;

	boolean debugging = true;

	public void debug(String text) {
		if (debugging == true) {
			log(text);
		}
	}

	// Epic walking method attempt #1

	// Method 1/6
	private boolean tileInNextRange(RSTile t) {
		return calc.distanceBetween(t, getMyPlayer().getLocation()) < nextStep;
	}

	// Method 2/6
	private int step(ArrayList<RSTile> path) {
		if (calc.distanceBetween(getMyPlayer().getLocation(),
				path.get(path.size() - 1)) < 2) {
			return path.size();
		}
		RSTile dest = walking.getDestination();
		int index = -1;
		int shortestDist = 0, dist, shortest = -16;
		if (dest != null) {
			for (int i = 0; i < path.size(); i++) {
				dist = (int) calc.distanceBetween(path.get(i), dest);
				if (shortest < 0 || shortestDist > dist) {
					shortest = i;
					shortestDist = dist;
				}
			}
		}
		for (int i = path.size() - 1; i >= 0; i--) {
			if (tileInNextRange(path.get(i))) {
				index = i;
				break;
			}
		}
		if (index >= 0
				&& (dest == null || (index > shortest) || !getMyPlayer()
						.isMoving())) {
			walkTile(path.get(index), 0, 0);
			sleep(random(180, 420, 265, 50));
			nextStep = random(15, 22);
			return index;
		}
		return -1;
	}

	// Method 3/6
	private int random(int lo, int hi, int mean, int sd) {
		java.util.Random r = new java.util.Random();
		int rand;
		do {
			rand = (int) (r.nextGaussian() * sd + mean);
		} while (rand < lo || rand >= hi);
		return rand;
	}

	// Method 4/6
	private boolean walkTile(RSTile t, int x, int y) {
		RSTile dest = new RSTile(t.getX() + random(0, x), t.getY()
				+ random(0, y));
		Point p = calc.tileToMinimap(dest);
		if (p.x != -1 && p.y != -1) {
			mouse.move(p);
			Point p2 = calc.tileToMinimap(dest);
			if (p2.x != -1 && p2.y != -1) {
				mouse.click(p2, true);
				return true;
			}
		}
		return false;
	}

	// Method 5/6
	private ArrayList<RSTile> generatePath(Line[] lines) {
		double minStep = 3, maxStep = 13, wander = random(2.1, 3.9);
		if (lines.length < 2) {
			return null;
		}
		ArrayList<RSTile> path = new ArrayList<RSTile>();
		Line l1, l2 = lines[0];
		double distFromCenter = random(0, l2.getDistance() + 1);
		RSTile p = l2.translate((int) distFromCenter);
		distFromCenter = l2.getDistance() / 2 - distFromCenter;
		double centerXdist, centerYdist, line1Xdist, line1Ydist, line2Xdist, line2Ydist;
		double line1dist, line2dist, centerDist;
		double x, y;
		double distOnLine, last, cap1, cap2, move;
		double distFromCenterX1, distFromCenterY1, distFromCenterX2, distFromCenterY2;
		double force1, force2, slopeX, slopeY, slopeDist;
		boolean finished;
		int lastX = p.getX(), lastY = p.getY(), curX, curY;
		double dist, xdist, ydist;
		for (int i = 1; i < lines.length; i++) {
			l1 = l2;
			l2 = lines[i];
			centerXdist = l2.getCenterX() - l1.getCenterX();
			centerYdist = l2.getCenterY() - l1.getCenterY();
			centerDist = Math.sqrt(centerXdist * centerXdist + centerYdist
					* centerYdist);
			line1Xdist = l2.getX() - l1.getX();
			line1Ydist = l2.getY() - l1.getY();
			line2Xdist = l2.getX2() - l1.getX2();
			line2Ydist = l2.getY2() - l1.getY2();
			centerXdist /= centerDist;
			centerYdist /= centerDist;
			line1Xdist /= centerDist;
			line1Ydist /= centerDist;
			line2Xdist /= centerDist;
			line2Ydist /= centerDist;
			distOnLine = 0;
			last = 0;
			finished = false;
			while (!finished) {
				distOnLine += random(minStep, maxStep);
				if (distOnLine >= centerDist) {
					distOnLine = centerDist;
					finished = true;
				}
				x = centerXdist * distOnLine + l1.getCenterX();
				y = centerYdist * distOnLine + l1.getCenterY();
				distFromCenterX1 = x - (line1Xdist * distOnLine + l1.getX());
				distFromCenterY1 = y - (line1Ydist * distOnLine + l1.getY());
				distFromCenterX2 = x - (line2Xdist * distOnLine + l1.getX2());
				distFromCenterY2 = y - (line2Ydist * distOnLine + l1.getY2());
				slopeX = distFromCenterX2 - distFromCenterX1;
				slopeY = distFromCenterY2 - distFromCenterY1;
				slopeDist = Math.sqrt(slopeX * slopeX + slopeY * slopeY);
				slopeX /= slopeDist;
				slopeY /= slopeDist;
				line1dist = Math.sqrt(distFromCenterX1 * distFromCenterX1
						+ distFromCenterY1 * distFromCenterY1);
				line2dist = Math.sqrt(distFromCenterX2 * distFromCenterX2
						+ distFromCenterY2 * distFromCenterY2);
				move = (distOnLine - last) / maxStep * wander;
				force1 = line1dist + distFromCenter;
				force2 = line2dist - distFromCenter;
				cap1 = Math.min(move, force1);
				cap2 = Math.min(move, force2);
				if (force1 < 0) {
					distFromCenter -= force1;
				} else if (force2 < 0) {
					distFromCenter += force2;
				} else {
					distFromCenter += random(-cap1, cap2);
				}
				if (finished) {
					RSTile t = l2.translateFromCenter(distFromCenter);
					curX = t.getX();
					curY = t.getY();
				} else {
					curX = (int) Math.round(distOnLine * centerXdist
							+ l1.getCenterX() + distFromCenter * slopeX);
					curY = (int) Math.round(distOnLine * centerYdist
							+ l1.getCenterY() + distFromCenter * slopeY);
				}
				xdist = curX - lastX;
				ydist = curY - lastY;
				dist = Math.sqrt(xdist * xdist + ydist * ydist);
				xdist /= dist;
				ydist /= dist;
				for (int j = 0; j < dist; j++) {
					path.add(new RSTile((int) Math.round(xdist * j + lastX),
							(int) Math.round(ydist * j + lastY)));
				}
				last = distOnLine;
				lastX = curX;
				lastY = curY;
			}
		}
		return cutUp(path);
	}

	// Method 6

	private ArrayList<RSTile> cutUp(ArrayList<RSTile> tiles) {
		ArrayList<RSTile> path = new ArrayList<RSTile>();
		int index = 0;
		while (index < tiles.size()) {
			path.add(tiles.get(index));
			index += random(9, 13);
		}
		if (!path.get(path.size() - 1).equals(tiles.get(tiles.size() - 1))) {
			path.add(tiles.get(tiles.size() - 1));
		}
		return path;
	}

	// Line class for epic walking method

	private class Line {
		private int x, y, xdist, ydist, x2, y2, centerX, centerY;
		private RSTile t1, t2;
		private double dist;

		public Line(int x1, int y1, int x2, int y2) {
			x = x1;
			y = y1;
			this.x2 = x2;
			this.y2 = y2;
			xdist = x2 - x1;
			ydist = y2 - y1;
			centerX = x + (int) (0.5 * xdist);
			centerY = y + (int) (0.5 * ydist);
			dist = Math.sqrt(xdist * xdist + ydist * ydist);
		}

		public int getCenterX() {
			return centerX;
		}

		public int getCenterY() {
			return centerY;
		}
		
		public RSTile getTile1() {
			return t1;
		}

		public RSTile getTile2() {
			return t2;
		}		

		private final Color POLY_FILL = new Color(20, 26, 167, 70);

		public void drawTo(Graphics g, Line line) {
			if (!calc.tileOnMap(t1) || !calc.tileOnMap(t2)) {
				return;
			}
			if (calc.tileOnMap(line.getTile1())
					&& calc.tileOnMap(line.getTile2())) {
				Point p1 = calc.tileToMinimap(t1);
				Point p2 = calc.tileToMinimap(t2);
				Point p3 = calc.tileToMinimap(line.getTile2());
				Point p4 = calc.tileToMinimap(line.getTile1());
				GeneralPath path = new GeneralPath();
				path.moveTo(p1.x, p1.y);
				path.lineTo(p2.x, p2.y);
				path.lineTo(p3.x, p3.y);
				path.lineTo(p4.x, p4.y);
				path.closePath();
				g.setColor(POLY_FILL);
				((Graphics2D) g).fill(path);
				((Graphics2D) g).draw(path);
			}
			Point last = null, p;
			g.setColor(color3);
			for (RSTile t : pathList) {
				if (calc.tileOnMap(t)) {
					p = calc.tileToMinimap(t);
					g.fillOval(p.x - 2, p.y - 2, 5, 5);
					if (last != null) {
						g.drawLine(p.x, p.y, last.x, last.y);
					}
					last = p;
				} else {
					last = null;
				}
			}
		}

		public int getX() {
			return x;
		}

		public int getY() {
			return y;
		}

		public int getX2() {
			return x2;
		}

		public int getY2() {
			return y2;
		}

		public double getDistance() {
			return dist;
		}

		public RSTile translate(double length) {
			return new RSTile((int) Math.round(length * (xdist / dist)) + x,
					(int) Math.round(length * (ydist / dist)) + y);
		}

		public RSTile translateFromCenter(double length) {
			return new RSTile((int) Math.round(centerX - (xdist / dist)
					* length), (int) Math.round(centerY - (ydist / dist)
					* length));
		}
	}

	// Epic walking method conversion from tile array

	private Line[] tilesToLines(RSTile[] tiles) {
		ArrayList<Line> temp = new ArrayList<Line>();

		for (int i = 0; i + 1 < tiles.length; i++) {
			temp.add(new Line(tiles[i].getX(), tiles[i].getY(), tiles[i + 1]
					.getX(), tiles[i + 1].getY()));
		}

		Line[] lines = new Line[temp.size()];
		for (int i = 0; i < temp.size(); i++) {
			lines[i] = temp.get(i);
		}
		return lines;
	}

	private void walk(RSTile[] tiles) {
		ArrayList<RSTile> path = generatePath(tilesToLines(tiles));
		step(path);
	}

	private int WALL_NORTH_WEST = 0x1;
	private int WALL_NORTH = 0x2;
	private int WALL_NORTH_EAST = 0x4;
	private int WALL_EAST = 0x8;
	private int WALL_SOUTH_EAST = 0x10;
	private int WALL_SOUTH = 0x20;
	private int WALL_SOUTH_WEST = 0x40;
	private int WALL_WEST = 0x80;
	private int BLOCKED = 0x100;
	private RSTile base;
	private int[][] flags;
	private int offX, offY;

	// Epic walking method end

	@Override
	public int loop() {
		if (game.isLoggedIn()) {
			if (firstRun) {
				if (inventory.containsAll(12183, 12155, CHARM, ITEM_ID)) {

					log("Script good to go!");
					if (!inventory.containsAll(12183, 12155, CHARM, ITEM_ID)) {

						log("Script not good to go :(");
						stopScript();
					}

				}
				firstRun = false;
			}

			int[][] flags = walking.getCollisionFlags(game.getPlane());
			if (flags != null) {
				base = game.getMapBase();
			}

			// Main script loop

			if (!inventory.containsOneOf(ITEM_ID) && inBankArea()) {
				BANK();
				sleep(1500, 2900);
				
				if (bank.isOpen() && bankCheck() == false) {
					stopScript();
				}

			}

			if (!inSumArea()
					&& inventory.containsAll(12183, 12155, CHARM, ITEM_ID)) {
				tosum();
			}

			RSObject CLOSEDDOOR = objects.getNearest(doorClosed);
			if (inDoorArea() && CLOSEDDOOR != null) {
				CLOSEDDOOR.doAction("Open");
				sleep(800, 1400);
				if (objects.getNearest(doorClosed) == null) {
				}
			}

			if (inventory.contains(ITEM_ID) && inventory.contains(12183)
					&& inSumArea()) {
				Make_Pouch();
			}

			if (!inBankArea() && !inventory.containsOneOf(ITEM_ID)) {

				toBank();

			}

			return random(250, 500);
		}
		return random(1000, 1500);
	}

	private boolean bankCheck() {
		debug("You no longer have any more ingredients, get some more to keep summoning!");
		RSItem temp = bank.getItem(ITEM_ID);
		if (bank.isOpen() && temp != null) {
			return true;
		}
		return false;
	}

	public void BANK() {

		debug("Bank CASE");

		RSObject bankBooth = objects.getNearest(BANK_BOOTHS);
		if (npcs.getNearest(6200) != null) {
			if (!inventory.contains(ITEM_ID)) {
				if (!bank.isOpen() && calc.tileOnScreen(BankTile)
						&& !getMyPlayer().isMoving()) {
					bankBooth.doAction("Use-Quickly");
					sleep(1200, 1900);
				}
				if (getMyPlayer().isMoving()) {
					sleep(400, 800);
				}

				if (bank.isOpen()) {

					bank.depositAllExcept(12183, 12155, CHARM, 8009, 8013);
					sleep(300, 1000);

					for (int y = 0; y < 150; y++) {
						if (bank.getCount(ITEM_ID) >= 1
								|| bank.getCount(CHARM) >= 1
								|| inventory.getCount(12155) <= 1
								|| inventory.getCount(12183) <= 1) {
							bank.withdraw(ITEM_ID, 0);
							for (int o = 0; o < 75
									&& !inventory.containsOneOf(ITEM_ID); o++)
								sleep(random(20, 30));
							if (!inventory.containsOneOf(ITEM_ID))
								return;
							break;
						}

					}
				}
			}

		}

	}

	public void toBank() {

		debug("toBank CASE");

		RSItem tab = inventory.getItem(8009);
		// RSTtem
		if (!inventory.contains(ITEM_ID)) {
			if (objects.getNearest(28716) != null
					&& !inventory.contains(ITEM_ID)) {
				if (tab != null && getMyPlayer().getAnimation() == -1) {
					tab.doClick(true);
					sleep(1000);
				} else {
					action(objects.getNearest(28714), "Climb");
					sleep(800, 1600);

				}
			}
		}

		RSObject CLOSEDDOOR = objects.getNearest(doorClosed);
		if (!inBankArea() && !calc.tileOnScreen(BankTile)) {
			pathList = generatePath(LinetoBank);
			step(pathList);

			if (inDoorArea() && CLOSEDDOOR != null) {
				CLOSEDDOOR.doAction("Open");
				sleep(1500, 2900);
				if (objects.getNearest(doorClosed) == null) {
				}
			}

		}

	}

	private final void tosum() {

		debug("tosum CASE");

		final RSItem tab = inventory.getItem(8013);

		if (!inTavArea()) {
			pathList = generatePath(LinetoTav);
			step(pathList);
		}

		if (inTavArea() && !objects.getNearest(hatch).isOnScreen()) {
			camera.turnToObject(objects.getNearest(hatch));
		}

		if (objects.getNearest(hatch) != null && !getMyPlayer().isMoving()) {
			action(objects.getNearest(4039), "Climb");
			sleep(800, 1400);
		}
		if (objects.getNearest(hatch) != null && !getMyPlayer().isMoving()) {
			action(objects.getNearest(4039), "Open");
			sleep(400, 900);
		}
	}

	private final void Make_Pouch() {

		if (inSumArea() && inventory.containsAll(12183, 12155, CHARM, ITEM_ID)) {
			if (inSumArea() && !objects.getNearest(28716).isOnScreen()) {
				camera.turnTo(objects.getNearest(28716));
			}
			if (!interfaces.get(79).isValid()) {
				open(28716);
				sleep(1000, 1600);
			} else if (interfaces.get(79).isValid()) {
				Pouch p = pouch.get(PLACE);
				if (!interfaces.getComponent(79, 16).getArea()
						.contains(p.getInterface().getCenter()))
					mouse.click(p.getLocation(), true);
				if (interfaces.getComponent(79, 16).getArea()
						.contains(p.getInterface().getCenter()))
					if (p.getInterface().doAction("All")) {
						sleep(3500, 4800);
					}
			}
		}
	}

	private void open(int id) {
		RSObject c = objects.getNearest(id);
		action(c, "Infuse-pouch");
	}

	private void AddPouch() {
		pouch.add(new Pouch("Spirit wolf pouch", 0, null));
		pouch.add(new Pouch("Dreadfowl pouch", 1, null));
		pouch.add(new Pouch("Spirit spider pouch", 2, null));
		pouch.add(new Pouch("Thorny snail pouch", 3, null));
		pouch.add(new Pouch("Granite crab pouch", 4, null));
		pouch.add(new Pouch("Spirit mosquito pouch", 5, null));
		pouch.add(new Pouch("Desert wyrm pouch", 6, null));
		pouch.add(new Pouch("Spirit scorpion pouch", 7, null));

		pouch.add(new Pouch("Spirit tz-kih pouch", 8, null));
		pouch.add(new Pouch("Albino rat pouch", 9, null));
		pouch.add(new Pouch("Spirit kalphite pouch", 10, null));
		pouch.add(new Pouch("Compost mound pouch", 11, null));
		pouch.add(new Pouch("Giant chinchompa pouch", 12, null));
		pouch.add(new Pouch("Vampire bat pouch", 13, null));
		pouch.add(new Pouch("Honey badger pouch", 14, null));
		pouch.add(new Pouch("Beaver pouch", 15, null));

		pouch.add(new Pouch("Void ravager pouch", 16, null));
		pouch.add(new Pouch("Void spinner pouch", 17, null));
		pouch.add(new Pouch("Void torcher pouch", 18, null));
		pouch.add(new Pouch("Void shifter pouch", 19, null));
		pouch.add(new Pouch("Bronze minotaur pouch", 20, null));
		pouch.add(new Pouch("Bull ant pouch", 21, null));
		pouch.add(new Pouch("Macaw pouch", 22, null));
		pouch.add(new Pouch("Evil turnip pouch", 23, null));
		pouch.add(new Pouch("Sp. cockatrice pouch", 24, null));

		pouch.add(new Pouch("Sp. guthatrice pouch", 25, null));
		pouch.add(new Pouch("Sp. saratrice pouch", 26, null));
		pouch.add(new Pouch("Sp. zamatrice pouch", 27, null));
		pouch.add(new Pouch("Sp. pengatrice pouch", 28, null));
		pouch.add(new Pouch("Sp. coraxatrice pouch", 29, null));
		pouch.add(new Pouch("Sp. vulatrice pouch", 30, null));
		pouch.add(new Pouch("Iron minotaur pouch", 31, null));
		pouch.add(new Pouch("Pyrelord pouch", 32, null));
		pouch.add(new Pouch("Magpie pouch", 33, null));

		pouch.add(new Pouch("Bloated leech pouch", 34, null));
		pouch.add(new Pouch("Spirit terrorbird pouch", 35, null));
		pouch.add(new Pouch("Abyssal parasite pouch", 36, null));
		pouch.add(new Pouch("Spirit jelly pouch", 37, null));
		pouch.add(new Pouch("Steel minotaur pouch", 38, null));
		pouch.add(new Pouch("Ibis pouch", 36, null));
		pouch.add(new Pouch("Spirit kyatt pouch", 40, null));
		pouch.add(new Pouch("Spirit larupia pouch", 41, null));
		pouch.add(new Pouch("Spirit graahk pouch", 42, null));

		pouch.add(new Pouch("Karam. overlord pouch", 43, new Point(487, 259)));
		pouch.add(new Pouch("Smoke devil pouch", 44, new Point(487, 259)));
		pouch.add(new Pouch("Abyssal lurker pouch", 45, new Point(487, 259)));
		pouch.add(new Pouch("Spirit cobra pouch", 46, new Point(487, 259)));
		pouch.add(new Pouch("Stranger plant pouch", 47, new Point(487, 259)));
		pouch.add(new Pouch("Mithril minotaur pouch", 48, new Point(487, 259)));
		pouch.add(new Pouch("Barker toad pouch", 49, new Point(487, 259)));
		pouch.add(new Pouch("War tortoise pouch", 50, new Point(487, 259)));
		pouch.add(new Pouch("Bunyip pouch", 51, new Point(487, 259)));

		pouch.add(new Pouch("Fruit bat pouch", 52, new Point(487, 259)));
		pouch.add(new Pouch("Ravenous locust pouch", 53, new Point(487, 259)));
		pouch.add(new Pouch("Arctic bear pouch", 54, new Point(487, 259)));
		pouch.add(new Pouch("Phoenix pouch", 55, new Point(487, 259)));
		pouch.add(new Pouch("Obsidian golem pouch", 56, new Point(487, 259)));
		pouch.add(new Pouch("Granite lobster pouch", 57, new Point(487, 259)));
		pouch.add(new Pouch("Praying mantis pouch", 58, new Point(487, 259)));
		pouch.add(new Pouch("Forge regent pouch", 59, new Point(487, 259)));
		pouch.add(new Pouch("Adamant minotaur pouch", 60, new Point(487, 259)));

		pouch.add(new Pouch("Talon beast pouch", 61, new Point(487, 259)));
		pouch.add(new Pouch("Giant ent pouch", 62, new Point(487, 259)));
		pouch.add(new Pouch("Fire titan pouch", 63, new Point(487, 259)));
		pouch.add(new Pouch("Moss titan pouch", 64, new Point(487, 259)));
		pouch.add(new Pouch("Ice titan pouch", 65, new Point(487, 259)));
		pouch.add(new Pouch("Hydra pouch", 66, new Point(487, 259)));
		pouch.add(new Pouch("Spirit dagannoth pouch", 67, new Point(487, 259)));
		pouch.add(new Pouch("Lava titan pouch", 68, new Point(487, 259)));

		pouch.add(new Pouch("Swamp titan pouch", 69, new Point(487, 259)));

		pouch.add(new Pouch("Rune minotaur pouch", 70, new Point(487, 259)));
		pouch.add(new Pouch("Unicorn stallion pouch", 71, new Point(487, 259)));

		pouch.add(new Pouch("Geyser titan pouch", 72, new Point(485, 300)));
		pouch.add(new Pouch("Wolpertinger pouch", 73, new Point(485, 300)));
		pouch.add(new Pouch("Abyssal titan pouch", 74, new Point(485, 300)));
		pouch.add(new Pouch("Iron titan pouch", 75, new Point(485, 300)));
		pouch.add(new Pouch("Pack yak pouch", 76, new Point(485, 300)));
		pouch.add(new Pouch("Steel titan pouch", 77, new Point(485, 300)));
	}

	private void action(RSObject c, String str) {
		if (c != null) {
			if (c.isOnScreen()) {
				c.doAction(str);
				sleep(1000);
				return;
			}
		}
		return;
	}

	public class Pouch {

		private String Name;
		private int POUCH_ID;
		private Point point;

		public Pouch(String name, int interfacesID, Point p) {
			this.Name = name;
			this.POUCH_ID = interfacesID;
			this.point = p;
		}

		public String getName() {
			return Name;
		}

		public RSComponent getInterface() {
			return interfaces.getComponent(79, 16).getComponent(
					(POUCH_ID * 5) + 2);
		}

		public Point getLocation() {
			return point;
		}

		public int getIndex() {
			return POUCH_ID;
		}
	}

	public class GUISum extends JFrame {
		/**
		 * 
		 */
		private static final long serialVersionUID = 7479107256377081984L;

		public GUISum() {
			initComponents();
		}

		private String[] inf() {
			LinkedList<String> str = new LinkedList<String>();
			for (Pouch p : pouch)
				str.add(p.getName());
			return str.toArray(new String[str.size()]);
		}

		private void Start(ActionEvent e) {
			String c1 = comboBox1.getSelectedItem().toString();
			String c2 = comboBox2.getSelectedItem().toString();
			String s = this.textField1.getText();
			for (Pouch p : pouch) {
				if (p.getName().contains(c1)) {
					PLACE = p.getIndex();
				}
			}
			ITEM_ID = Integer.parseInt(s);
			CHARM = inventory.getItemID(c2);
			log("Charm ID:  " + CHARM + "  Item ID: " + ITEM_ID);
			log("Pouch ID: " + PLACE);

			isUp = false;
			sleep(50);
			this.dispose();
		}

		private void initComponents() {
			// JFormDesigner - Component initialization - DO NOT MODIFY
			// //GEN-BEGIN:initComponents
			Start = new JButton();
			comboBox1 = new JComboBox();
			label1 = new JLabel();
			comboBox2 = new JComboBox();
			label2 = new JLabel();
			textField1 = new JTextField();
			label3 = new JLabel();

			// ======== this ========
			setTitle("Fally Summoner");
			Container contentPane = getContentPane();
			contentPane.setLayout(null);

			// ---- Start ----
			Start.setText("Start");
			Start.addActionListener(new ActionListener() {
				public void actionPerformed(ActionEvent e) {
					Start(e);
				}
			});
			comboBox1.setModel(new DefaultComboBoxModel(this.inf()));
			contentPane.add(Start);
			Start.setBounds(10, 195, 495, Start.getPreferredSize().height);
			contentPane.add(comboBox1);
			comboBox1.setBounds(5, 50, 505, 35);

			// ---- label1 ----
			label1.setText("Pouch Type:");
			contentPane.add(label1);
			label1.setBounds(205, 25, 100, 20);

			// ---- comboBox2 ----
			comboBox2.setModel(new DefaultComboBoxModel(
					new String[] { "Gold charm", "Green charm",
							"Crimson charm", "Blue charm" }));
			contentPane.add(comboBox2);
			comboBox2.setBounds(new Rectangle(new Point(105, 105), comboBox2
					.getPreferredSize()));

			// ---- label2 ----
			label2.setText("Charm Kind:");
			contentPane.add(label2);
			label2.setBounds(20, 110, 75, label2.getPreferredSize().height);
			contentPane.add(textField1);
			textField1.setBounds(105, 165, 160,
					textField1.getPreferredSize().height);

			// ---- label3 ----
			label3.setText("Item ID:");
			contentPane.add(label3);
			label3.setBounds(10, 165, 75, 20);

			{ // compute preferred size
				Dimension preferredSize = new Dimension();
				for (int i = 0; i < contentPane.getComponentCount(); i++) {
					Rectangle bounds = contentPane.getComponent(i).getBounds();
					preferredSize.width = Math.max(bounds.x + bounds.width,
							preferredSize.width);
					preferredSize.height = Math.max(bounds.y + bounds.height,
							preferredSize.height);
				}
				Insets insets = contentPane.getInsets();
				preferredSize.width += insets.right;
				preferredSize.height += insets.bottom;
				contentPane.setMinimumSize(preferredSize);
				contentPane.setPreferredSize(preferredSize);
			}
			pack();
			setLocationRelativeTo(getOwner());
			// JFormDesigner - End of component initialization
			// //GEN-END:initComponents
		}

		// JFormDesigner - Variables declaration - DO NOT MODIFY
		// //GEN-BEGIN:variables
		private JButton Start;
		private JComboBox comboBox1;
		private JLabel label1;
		private JComboBox comboBox2;
		private JLabel label2;
		private JTextField textField1;
		private JLabel label3;
		private JLabel label4;
		private JComboBox comboBox3;
		// JFormDesigner - End of variables declaration //GEN-END:variables
	}

	@Override
	public void messageReceived(MessageEvent e) {
		String msg = e.getMessage();
		if (msg.contains("This pouch requires")) {
			log("Were either out of charms, ingredients, or shards, so the script is stopping =(");
			stopScript();
		}

	}

	public void onFinish() {
		log("------ Thank you for using Trolololo's Falador Summoner ^_^ ------");
		log("Remember to comment!");
		stopScript();
	}

}